package web

import (
	"bytes"
	"io"
	"net/http"

	"github.com/bytedance/sonic"
)

type HTTPHeader map[string]string

var (
	HTTPEmptyHeader HTTPHeader
)

func SendHttpRequest(method, url string, data interface{}, headers HTTPHeader) (res []byte, err error) {
	jsonStr, _ := sonic.Marshal(data)
	client := &http.Client{}
	req, err := http.NewRequest(method, url, bytes.NewBuffer(jsonStr))
	if err != nil {
		return
	}

	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0")
	req.Header.Set("Content-Type", "application/json; charset=utf-8")
	// req.Header.Set("Content-Type","text/plain;charset=UTF-8")
	req.Header.Set("Accept", "application/json, text/plain, */*")

	for k, v := range headers {
		req.Header.Set(k, v)
	}

	resp, err := client.Do(req)
	if err != nil {
		return
	} else if resp != nil {
		defer resp.Body.Close()
		res, err = io.ReadAll(resp.Body)
	}
	return
}

type HttpFull struct{}

func (f *HttpFull) Connect(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("CONNECT", url, data, headers)
}

func (f *HttpFull) Delete(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("DELETE", url, data, headers)
}

func (f *HttpFull) Get(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("GET", url, data, headers)
}

func (f *HttpFull) Head(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("HEAD", url, data, headers)
}

func (f *HttpFull) Options(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("OPTIONS", url, data, headers)
}

func (f *HttpFull) Patch(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("PATCH", url, data, headers)
}

func (f *HttpFull) Post(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("POST", url, data, headers)
}

func (f *HttpFull) Put(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("PUT", url, data, headers)
}

func (f *HttpFull) Trace(url string, data interface{}, headers HTTPHeader) ([]byte, error) {
	return SendHttpRequest("TRACE", url, data, headers)
}

type HttpSimple struct{}

func (s *HttpSimple) Connect(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("CONNECT", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Delete(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("DELETE", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Get(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("GET", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Head(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("HEAD", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Options(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("OPTIONS", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Patch(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("PATCH", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Post(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("POST", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Put(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("PUT", url, data, HTTPEmptyHeader)
}

func (s *HttpSimple) Trace(url string, data interface{}) ([]byte, error) {
	return SendHttpRequest("TRACE", url, data, HTTPEmptyHeader)
}
